package com.leo.foodmaster.admin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.leo.foodmaster.admin.system.entity.SysDictData;
import com.leo.foodmaster.admin.system.entity.SysDictType;
import com.leo.foodmaster.admin.system.mapper.SysDictDataMapper;
import com.leo.foodmaster.admin.system.mapper.SysDictTypeMapper;
import com.leo.foodmaster.admin.system.service.ISysDictTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leo.foodmaster.commons.constants.AuthConstants;
import com.leo.foodmaster.commons.entity.Result;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 字典类型表 服务实现类
 * </p>
 *
 * @author Leo
 * @since 2021-06-29
 */
@Slf4j
@Service
@AllArgsConstructor
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements ISysDictTypeService {
    private final SysDictDataMapper dictDataMapper;
    private final RedisTemplate<String, String> redisTemplate;

    /**
     * 项目启动时，初始化字典到缓存
     */
    @PostConstruct
    public void init() {
        log.info("将字典数据存入Redis。。。");
        listAllDict();
    }

    /**
     * 查询所有字典数据，并将他们存入缓存
     */
    @Override
    public void listAllDict() {
        List<SysDictType> dictTypeList = this.list();
        for (SysDictType dictType : dictTypeList) {
            List<SysDictData> dictDataList = dictDataMapper.selectList(Wrappers.lambdaQuery(SysDictData.class)
                    .eq(SysDictData::getDictType, dictType.getDictType()));
            if (!dictDataList.isEmpty()) {
                // 将字典数据存入缓存
                String dictKey = AuthConstants.SYS_DICT_KEY + dictType.getDictType();
                refreshDictToCache(dictKey, dictDataList);
            }
        }
    }

    /**
     * 刷新字典数据到缓存
     *  @param dictKey redis 键
     *  @param dictDataList 字典数据列表
     */
    @Override
    public void refreshDictToCache(String dictKey, List<SysDictData> dictDataList) {
        // 删除原来的数据
        redisTemplate.delete(dictKey);
        // 刷新字典数据到redis
        redisTemplate.opsForValue().set(dictKey, JSONUtil.toJsonPrettyStr(dictDataList));
    }

    /**
     * 根据字典类型查询字典数据
     * @param dictType 字典类型
     * @return List<SysDictData>
     */
    @Override
    public List<SysDictData> selectDictDataByType(String dictType) {
        // 从缓存中查询
        String dictKey = AuthConstants.SYS_DICT_KEY + dictType;
        String jsonStr = redisTemplate.opsForValue().get(dictKey);
        return JSONUtil.parseArray(jsonStr).toList(SysDictData.class);
    }

    /**
     * 条件分页查询数据字典类型
     * @param page 分页参数
     * @param name 字典类型名称
     * @param status 字典类型状态
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return IPage<SysDictType>
     */
    @Override
    public IPage<SysDictType> getDictTypePageList(Page<SysDictType> page, String name, String status, String beginTime, String endTime) {
        LambdaQueryWrapper<SysDictType> qw = Wrappers.lambdaQuery(SysDictType.class)
                .like(StrUtil.isNotBlank(name), SysDictType::getName, name)
                .eq(StrUtil.isNotBlank(status), SysDictType::getStatus, status)
                .ge(StrUtil.isNotBlank(beginTime), SysDictType::getCreateTime, beginTime)
                .le(StrUtil.isNotBlank(endTime), SysDictType::getCreateTime, endTime);
        return page(page, qw);
    }

    /**
     * 根据Ids删除字典类型
     * @param dictTypeIds 字典类型Ids
     * @return Result<Object>
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<Object> deleteSysDictType(String dictTypeIds) {
        String[] dictTypeIdArray = dictTypeIds.split(StrUtil.COMMA);
        List<Long> dictTypeIdList = new ArrayList<>();
        for (String dictTypeId : dictTypeIdArray) {
            SysDictType dictType = getById(dictTypeId);
            // 删除字典类型对应的字典数据
            dictDataMapper.delete(Wrappers.lambdaUpdate(SysDictData.class)
            .eq(BeanUtil.isNotEmpty(dictType), SysDictData::getDictType, dictType.getDictType()));
            dictTypeIdList.add(Long.parseLong(dictTypeId));
        }
        // 删除字典类型
        boolean remove = removeByIds(dictTypeIdList);
        // 刷新字典数据缓存
        if (remove) {
            listAllDict();
        }
        return Result.success();
    }


}
